#include <cellcsp.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <csp_debug.h>
#include "../../shared/sor.h"
#include "StopWatch.h"


int write_file(char *fname, void *data, size_t size_elem, size_t n_elem){
	FILE * pFile;
	size_t res;
	pFile = fopen (fname , "wb");

	res = fwrite (data , size_elem, n_elem, pFile);

	fclose(pFile);

	return res;
}

void setup(float *trap_data, int height, int width){
	int x,y;
	/* Initial state */
	for(y=0;y<height-1;y++)           //Setup left side temp
		trap_data[y*width+0]=-273.15;

	for(y=0;y<height-1;y++)           //Setup right side temp
		trap_data[y*width+width-1]=-273.15;

	for(x=0; x<width; x++)            //Setup top temp
		trap_data[0*width+x]=40.0;

	for(x=0; x<width; x++)            //Setup bottom temp
		trap_data[(height-1)*width+x]=-273.15;
}


int main(){


	char buf[256];

	float* data = (float*) _malloc_align(sizeof(float)*HEIGHT*WIDTH, 7);
	setup(data, HEIGHT, WIDTH);

	if( HEIGHT % N_WORKERS ){
		printf("Height %i cannot be divided by %i workers.\n", HEIGHT, N_WORKERS);	
	}
	
	sw_init();
	sw_start();

	char *worker    = "sor_worker_process";
	char *init      = "sor_init_process";

	CSPConfig conf;

	conf.add_csp_program("./tasks/sor_worker_process",    worker   );
	conf.add_csp_program("./tasks/sor_init_process",      init     );



	//int i;
	//for(i=0; i < HEIGHT*WIDTH; i++){
	//	data[i] = 3.0;
	//}

	//printf("sizeof(float)=%i", sizeof(float));


	//printMatrix(data, HEIGHT, WIDTH, "PPU", 0);

	set_shared_address(data);

	CellCSP_start(conf);


	Parallel par( new CSPProcess(init), NULL);
	for(int i=0; i < N_WORKERS; i++){
		par.Add(new CSPProcess(worker));
	}

	par.Run();

	CellCSP_end();

	sw_stop();
	sw_timeString(buf);
	printf("Time taken: %s\n", buf);
	
	char *fname = "frosty.csp.data";

	int nbytes = write_file(fname, data, sizeof(float), HEIGHT*WIDTH);
	printf("%i bytes written to %s, dimensions: h=%i, w=%i\n", nbytes, fname, HEIGHT,WIDTH);

	return 0;
}
